package com.horqian.api.oktoberfest

import android.os.Build
import android.os.Bundle
import android.text.InputType
import android.text.TextUtils
import android.text.method.PasswordTransformationMethod
import android.util.Log
import android.view.Window
import android.view.WindowManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.common.pos.api.util.PosUtil
import com.google.gson.Gson
import com.hello.scan.ScanCallBack
import com.hello.scan.ScanTool
import com.horqian.api.oktoberfest.databinding.ActivityMainBinding
import com.horqian.api.oktoberfest.net.LSZNResponseBean
import com.horqian.api.oktoberfest.net.ResponseBean
import com.lxj.xpopup.XPopup
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import java.util.concurrent.TimeUnit


class MainActivity : AppCompatActivity(), ScanCallBack {

    private var autoCloseDoorTime = 0L

    private val mBinding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    private val loadingLSZNDialog by lazy {
        XPopup.Builder(this).asLoading("官方小程序预约码验证中")
    }

    private val loadingQDYXDialog by lazy {
        XPopup.Builder(this).asLoading("青岛严选预约码验证中")
    }

    private val client by lazy {
        OkHttpClient().newBuilder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .build()
    }
    var closeDoorJob: Job? = null

    private var closeTipJob: Job? = null

    private val mTipDialog by lazy {
        TipDialog(this)
    }
    private val sDevices: Map<String, Pair<String, Int>> = mutableMapOf(
        "TPS508" to Pair("/dev/ttyACM0", 115200),
        "TPS360" to Pair("/dev/ttyACM0", 115200),
        "TPS537" to Pair("/dev/ttyACM0", 115200),
        "F2" to Pair("/dev/ttyACM0", 115200),
        "D2" to Pair("/dev/ttyHSL0", 115200), // D2串口模式
        //"D2" to Pair("/dev/ttyACM0", 115200), // D2U转串模式
        "D2M" to Pair("/dev/ttyHSL0", 115200), //串口模式
        "TPS980" to Pair("/dev/ttyS0", 115200),
        "TPS980P" to Pair("/dev/ttyS0", 115200),
        //"TPS980P" to Pair("/dev/ttyS0", 9600),
        "TPS530" to Pair("/dev/ttyUSB0", 115200),
        "TPS580P" to Pair("/dev/ttyHSL0", 115200),
        "T20" to Pair("/dev/ttyS7", 115200),
        "C31" to Pair("/dev/ttyACM0", 115200),
        "SAI-IDA-730" to Pair("/dev/ttyS0", 9600)
    )
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //背景图片覆盖系统状态栏

        this.supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
        this.window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
        setContentView(mBinding.root)

        autoCloseDoorTime = SPUtils.getLongValue(this, "autoCloseDoorTime", 19000L)
        if (!initScanTool()) {
            Toast.makeText(this, "该机型还没适配[${Build.MODEL}]", Toast.LENGTH_SHORT).show()
        } else {
            ScanTool.GET.playSound(true)
        }
        mBinding.ivSetting.setOnClickListener {
            XPopup.Builder(this).asInputConfirm(
                "请输入管理员密码", ""
            ) { pwd ->
                if (pwd=="000912"){
                    XPopup.Builder(this).asInputConfirm(
                        "请输入自动关门时间", ""
                    ) { text ->
                        try {
                            autoCloseDoorTime = text.toLong()
                            SPUtils.putValue(this, "autoCloseDoorTime", autoCloseDoorTime)
                            Toast.makeText(this, "设置成功：${autoCloseDoorTime}", Toast.LENGTH_SHORT).show()
                        } catch (e: Exception) {
                            Toast.makeText(this, "设置失败，输入时长有误", Toast.LENGTH_SHORT).show()
                        }
                    }.apply {
                        show()
                        lifecycleScope.launch(Dispatchers.IO) {
                            delay(500)
                            lifecycleScope.launch(Dispatchers.Main) {
                                editText.inputType = InputType.TYPE_CLASS_NUMBER
                            }
                        }
                    }
                }else{
                    Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show()
                }
            }.apply {
                show()
                lifecycleScope.launch(Dispatchers.IO) {
                    delay(500)
                    lifecycleScope.launch(Dispatchers.Main) {
                        editText.transformationMethod = PasswordTransformationMethod.getInstance()
                    }
                }
            }
        }
    }


    /**
     * 判断使用模式
     *
     * @return 返回true表示表示该机型已经适配，false表示该机型还没有适配
     */
    private fun initScanTool(): Boolean {
        for ((key, value) in sDevices) {
            if (key == Build.MODEL) {
                value.let {
                    Log.e("Hello", "judgeModel == > $key")
                    Log.e("Hello", "path == > ${it.first}")
                    Log.e("Hello", "baud rate == > ${it.second}")
                    ScanTool.GET.initSerial(this, it.first, it.second, this@MainActivity)
                    return true
                }
            }
        }

        return false
    }

    private suspend fun openTheDoor(){
        lifecycleScope.launch(Dispatchers.IO) {
            lifecycleScope.launch(Dispatchers.Main) {
                try {
                    PosUtil.setRelayPower(0)
                } catch (_: UnsatisfiedLinkError) {

                } catch (_: Throwable) {

                }
                Log.d("测试", "关")
            }
            delay(500)
            lifecycleScope.launch(Dispatchers.Main) {
                Log.d("测试", "开")
                val openCode = try {
                    PosUtil.setRelayPower(1)
                } catch (e: UnsatisfiedLinkError) {
                    -1
                }
                mTipDialog.showTip(true)
                if (closeTipJob != null && closeTipJob?.isActive == true) {
                    closeTipJob?.cancel()
                }
                closeTipJob = lifecycleScope.launch(Dispatchers.IO) {
                    delay(3000)
                    lifecycleScope.launch(Dispatchers.Main) {
                        Log.d("测试", "show: 关闭！")
                        mTipDialog.dismiss()
                    }
                }
                if (closeDoorJob != null && closeDoorJob?.isActive == true) {
                    Log.d("测试", "取消上次任务 本次时长:${autoCloseDoorTime}")
                    closeDoorJob?.cancel()
                }
                closeDoorJob = lifecycleScope.launch(Dispatchers.IO) {
                    delay(autoCloseDoorTime)
                    val closeCode = try {
                        PosUtil.setRelayPower(0)
                    } catch (e: UnsatisfiedLinkError) {
                        -1
                    }
                    Log.d("测试", "关门code：${closeCode} 本次时长:${autoCloseDoorTime}")
                }
            }
        }
    }
    private suspend fun keepCloseTheDoor(errorMessage:String){
        lifecycleScope.launch(Dispatchers.Main) {
            mTipDialog.showTip(false,errorMessage)
            if (closeTipJob != null && closeTipJob?.isActive == true) {
                closeTipJob?.cancel()
            }
            closeTipJob = lifecycleScope.launch(Dispatchers.IO) {
                delay(3000)
                lifecycleScope.launch(Dispatchers.Main) {
                    Log.d("测试", "show: 关闭！")
                    mTipDialog.dismiss()
                }
            }
        }
    }
    private suspend fun queryLSZNInfo(barcode: String) {
        val serverUrl = "https://jstpjc.greenwater.tech:9094/wechat/ticketWriteOff"
        lifecycleScope.launch(Dispatchers.Main) {
            loadingLSZNDialog.show()
        }
        val barcode = barcode.replace("\n", "").replace("\r", "")
        val json = """
        {
            "id":"$barcode",
            "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkdyIsImV4cCI6MTcyNjAyMTczMywibWFwIjp7ImNyZWF0b3IiOiI5MjM3ODEwMzI4NDIzMSIsImFkbWluVXNlciI6IjkyMzc4MTAzMjg0MjMxIiwiZWRnZUFwaSI6ImVkZ2VBcGkifX0.0IPn446O4tMQGGbchcDR8myCcjjnYxbeDERK6nF9cT4"
        }
    """.trimIndent()

        val mediaType = MediaType.parse("application/json; charset=utf-8")
        val requestBody = RequestBody.create(mediaType, json)

        val request = Request.Builder()
            .url(serverUrl)
            .post(requestBody)
            .addHeader("Content-Type", "application/json")
            .build()

        val response = client.newCall(request).execute()

        lifecycleScope.launch(Dispatchers.Main) {
            if (loadingLSZNDialog.isShow) {
                loadingLSZNDialog.dismiss()
            }
        }

        if (response.isSuccessful) {
            val body = response.body().string()
            val info = Gson().fromJson(body, LSZNResponseBean::class.java)
            Log.d("测试", body)
            if (info.code == 0) {
                openTheDoor()
            } else {
                keepCloseTheDoor("核销失败：${info.message}")
            }
        } else {
            val str = response.body().string()
            lifecycleScope.launch(Dispatchers.Main) {
                Toast.makeText(this@MainActivity, "网络请求异常:\n${str}", Toast.LENGTH_LONG).show()
            }
        }




    }

    private suspend fun queryQDYXInfo(barcode: String) {
        val  server_url = "https://shop.qdyanxuan.com/beerVerify.php"
        lifecycleScope.launch(Dispatchers.Main) {
            loadingQDYXDialog.show()
        }
        val requestBody = FormBody.Builder().addEncoded("data", barcode).build()
        val request =
            Request.Builder().url(server_url)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .post(requestBody).build()
        val response = client.newCall(request).execute()
        lifecycleScope.launch(Dispatchers.Main) {
            if (loadingQDYXDialog.isShow) {
                loadingQDYXDialog.dismiss()
            }
        }

        if (response.isSuccessful) {
            val body = response.body().string()
            val info = Gson().fromJson(body, ResponseBean::class.java)
            Log.d("测试", body)
            if (info.code == 0) {
                openTheDoor()
            } else {
                keepCloseTheDoor(info.msg)
            }
        } else {
            val str = response.body().string()
            lifecycleScope.launch(Dispatchers.Main) {
                Toast.makeText(this@MainActivity, "网络请求异常:\n${str}", Toast.LENGTH_LONG).show()
            }
        }
    }


    override fun onInitScan(isSuccess: Boolean) {
        super.onInitScan(isSuccess)
        val str = if (isSuccess) "扫码初始化成功" else "扫码初始化失败"
        lifecycleScope.launch(Dispatchers.Main) {
            Toast.makeText(this@MainActivity, str, Toast.LENGTH_SHORT).show()
        }

    }

    override fun onScanCallBack(data: String?) {
        if (TextUtils.isEmpty(data)) return
        Log.e("Hello", "回调数据 == > $data")
        doQuery(data ?: "")

    }

    private fun doQuery(barcode: String) {
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                if (barcode.length < 4) {
                    throw Exception("不可核销二维码")
                }
                var barcodePrefix = barcode.substring(0,4)

                if (barcodePrefix.equals("LSZN")){
                    //黄发集团小程序发的预约码
                    //格式： LSZN475896996504004040
                    queryLSZNInfo(barcode)
                    lifecycleScope.launch(Dispatchers.Main) {
                        Toast.makeText(this@MainActivity, "官方小程序预约码核销成功，请通行！", Toast.LENGTH_SHORT).show()
                    }
                    Log.i("统计","官方小程序预约码核销${barcode}")
                }else if (barcodePrefix.equals("QDYX")){
                    //青岛严选小程序发的预约码
                    //格式： QDYX_475896996504004040
                    val barcode = barcode.replace(barcodePrefix+"_", "")
                    queryQDYXInfo(barcode)
                    lifecycleScope.launch(Dispatchers.Main) {
                        Toast.makeText(this@MainActivity, "渠道B预约码核销成功，请通行！", Toast.LENGTH_SHORT).show()
                    }
                    Log.i("统计","渠道B预约码核销${barcode}")
                }else if (barcodePrefix.equals("WNDK")){
                    //万能的卡，直接开门一次，仅限工作人员使用。
                    //测试阶段使用，正式开始后，去掉这一段。TODO
                    openTheDoor()
                    lifecycleScope.launch(Dispatchers.Main) {
                        Toast.makeText(this@MainActivity, "工作人员通行码，请通行！", Toast.LENGTH_SHORT).show()
                    }
                    Log.i("统计","工作人员通行码核销${barcode}")
                }else{
                    throw Exception("无效二维码\n$barcode")
                    Log.i("统计","无效二维码${barcode}")
                }
            } catch (e: Exception) {
                Log.e("调试", "网络错误:${e.message ?: ""}", e)
                lifecycleScope.launch(Dispatchers.Main) {
                    Toast.makeText(this@MainActivity, e.message ?: "", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        ScanTool.GET.release()
    }
}